#include "test.h"

#define free2(ptr) \
    do { \
        if (ptr) { \
            free(ptr); \
        } \
    } while (0)

static void malloc_size(int size)
{
    
    char * buf[16] = {0,};

    int i;

    for (i = 0; i < 16; i++)
    {
        buf[i] = malloc(size);
        if (buf[i]) {
            printf("malloc size %d %p\n", size, buf[i]);
            memset(buf[0], 0x5a, size);
        }
        else
        {
            break;
        }
    }

    for (i = 0; i < 16; i++)
    {
        if (buf[i]) {
            free(buf[i]);
        }
    }
}

static int mem_malloc_test(void)
{
    char * p;

    p = malloc(0);
    printf("malloc %p\n", p);
    free2(p);
    p = malloc(8);
    printf("malloc %p\n", p);
    free2(p);
    p = malloc(16);
    printf("malloc %p\n", p);
    free2(p);
    p = malloc(64);
    printf("malloc %p\n", p);
    free2(p);
    p = malloc(128);
    printf("malloc %p\n", p);
    free2(p);
    p = malloc(512);
    printf("malloc %p\n", p);
    free2(p);
    p = malloc(1024);
    printf("malloc 1024 %p\n", p);
    free2(p);
    p = malloc(2048);
    printf("malloc %p\n", p);
    free2(p);
    p = malloc(4096);
    printf("malloc %p\n", p);
    free2(p);
    p = malloc(4096 * 2);
    printf("malloc %p\n", p);
    free2(p);
    p = malloc(4096 * 10);
    printf("malloc %p\n", p);
    free2(p);
    p = malloc(4096 * 20);
    printf("malloc 4096 *20 %p\n", p);
    free2(p);
    p = malloc(4096 * 60);
    printf("malloc %p\n", p);
    free2(p);
    p = malloc(4096 * 100);
    printf("malloc %p\n", p);
    free2(p);

    p = malloc(0 + 1);
    printf("malloc %p\n", p);
    free2(p);
    p = malloc(8 + 1);
    printf("malloc %p\n", p);
    free2(p);
    p = malloc(16 + 1);
    printf("malloc %p\n", p);
    free2(p);
    p = malloc(64 + 1);
    printf("malloc %p\n", p);
    free2(p);
    p = malloc(128 + 1);
    printf("malloc %p\n", p);
    free2(p);
    p = malloc(512 + 1);
    printf("malloc %p\n", p);
    free2(p);
    p = malloc(1024 + 1);
    printf("malloc %p\n", p);
    free2(p);
    p = malloc(2048 + 1);
    printf("malloc %p\n", p);
    free2(p);
    p = malloc(4096 + 1);
    printf("malloc %p\n", p);
    free2(p);
    p = malloc(4096 * 2 + 1);
    printf("malloc %p\n", p);
    free2(p);
    p = malloc(4096 * 10 + 1);
    printf("malloc %p\n", p);
    free2(p);
    p = malloc(4096 * 20 + 1);
    printf("malloc %p\n", p);
    free2(p);
    p = malloc(4096 * 60 + 1);
    printf("malloc %p\n", p);
    free2(p);
    p = malloc(4096 * 100 + 1);
    printf("malloc %p\n", p);
    free2(p);

    char * buf[16] = {0,};

    int i;
    int size;
    for (size =8, i = 0; i < 16; i++, size *= 2)
    {
        buf[i] = malloc(size);
        if (buf[i]) {
            printf("malloc size %d %p\n", size, buf[i]);
            memset(buf[0], 0x5a, size);
        }
        else
        {
            break;
        }
    }

    for (i = 0; i < 16; i++)
    {
        if (buf[i]) {
            free(buf[i]);
        }
    }

    for (size =8, i = 0; i < 16; i++, size *= 2)
    {
        malloc_size(size);
    }
    return 0;
}

static void realloc_size(int size)
{
    char * buf[16] = {0,};

    int i;

    for (i = 0; i < 16; i++)
    {
        buf[i] = realloc(NULL, size);
        if (buf[i]) {
            printf("realloc size %d %p\n", size, buf[i]);
            memset(buf[0], 0x5a, size);
        }
        else
        {
            break;
        }
    }
    
    for (i = 0; i < 16; i++)
    {
        buf[i] = realloc(buf[i], size + 1);
        if (buf[i]) {
            printf("realloc size %d %p\n", size, buf[i]);
            memset(buf[0], 0x5a, size);
        }
        else
        {
            break;
        }
    }

    for (i = 0; i < 16; i++)
    {
        if (buf[i]) {
            free(buf[i]);
        }
    }
}

static int realloc_test(void)
{
    char * p;

    p = realloc(NULL, 8);
    printf("remalloc %p\n", p);
    free2(p);

    p = realloc(NULL, 64);
    printf("remalloc %p\n", p);
    free2(p);

    p = realloc(NULL, 512);
    printf("remalloc %p\n", p);
    free2(p);

    p = realloc(NULL, 4096);
    printf("remalloc %p\n", p);
    free2(p);

    p = realloc(NULL, 4096 * 10);
    printf("remalloc %p\n", p);
    free2(p);


    p = realloc(NULL, 8);
    printf("remalloc %p\n", p);
    
    p = realloc(p, 64);
    printf("remalloc %p\n", p);

    p = realloc(p, 512);
    printf("remalloc %p\n", p);

    p = realloc(p, 4096);
    printf("remalloc %p\n", p);

    p = realloc(p, 4096 * 10);
    printf("remalloc %p\n", p);

    p = realloc(p, 4096 * 100);
    printf("remalloc %p\n", p);
    free2(p);

    char * buf[16] = {0,};

    int i;
    int size;
    for (size =8, i = 0; i < 16; i++, size *= 2)
    {
        buf[i] = realloc(NULL, size);
        if (buf[i]) {
            printf("malloc size %d %p\n", size, buf[i]);
            memset(buf[0], 0x5a, size);
        }
        else
        {
            break;
        }
    }

    for (i = 0; i < 16; i++)
    {
        if (buf[i]) {
            free(buf[i]);
        }
    }

    for (size =8, i = 0; i < 16; i++, size *= 2)
    {
        realloc_size(size);
    }
    return 0;
}

int malloc_test(int argc, char *argv[])
{
	mem_malloc_test();
    mem_malloc_test();
    realloc_test();

    
	mem_malloc_test();
    mem_malloc_test();
    realloc_test();

    
	mem_malloc_test();
    mem_malloc_test();
    realloc_test();
    
    return 0;
}
